const crypto = require('crypto');
const axios = require('axios');
const JSON = require('json-bigint'); // 支持大数字处理

class SmsSendService {
    // 静态变量缓存公钥
    static PUBLIC_KEY = null;

    /**
     * 验证签名是否合法
     * @param {string} xAGCAuth - 请求头中的签名信息
     * @param {string} xAGCTimestamp - 请求头中的时间戳
     * @param {string} thirdSmsUrl - 验证码/通知接收地址
     * @param {Object} thirdSmsReq - POST请求体对象
     * @returns {Promise<boolean>} - 验证结果
     */
    static async verifyAuth(xAGCAuth, xAGCTimestamp, thirdSmsUrl, thirdSmsReq) {
        // 1. 检查时间戳是否过期（不超过三分钟）
        const allowedTimeWindowMs = 3 * 60 * 1000;
        const currentTime = Date.now();
        if (Math.abs(currentTime - parseInt(xAGCTimestamp)) > allowedTimeWindowMs) {
            throw new Error('Timestamp expired or invalid');
        }

        // 2. 拼接待验签字符串
        const dataToVerify = [
            'POST',
            thirdSmsUrl,
            xAGCTimestamp,
            JSON.stringify(thirdSmsReq)
        ].join('\n');

        // 3. 获取公钥（首次使用自动初始化）
        if (!SmsSendService.PUBLIC_KEY) {
            SmsSendService.PUBLIC_KEY = await SmsSendService.getPublicKey();
        }

        // 4. 验证签名
        return SmsSendService.verifySignature(dataToVerify, xAGCAuth, SmsSendService.PUBLIC_KEY);
    }

    /**
     * 获取认证服务的公钥
     * @returns {Promise<string>} - 公钥字符串
     */
    static async getPublicKey() {
        try {
            const response = await axios.get(
                'https://developer.huawei.com/consumer/cn/service/josp/agc/auth/keys'
            );

            if (response.status === 200) {
                const jsonData = response.data;
                // 获取第一个键的值
                const firstKey = Object.values(jsonData)[0];

                // 清理公钥格式
                return firstKey
                    .replace('-----BEGIN CERTIFICATE-----', '')
                    .replace('-----END CERTIFICATE-----', '')
                    .trim();
            } else {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
        } catch (error) {
            console.error('Failed to get public key:', error);
            throw error;
        }
    }

    /**
     * 验证签名
     * @param {string} data - 原始数据
     * @param {string} signature - base64编码的签名
     * @param {string} publicKey - PEM格式公钥
     * @returns {boolean} - 验证结果
     */
    static verifySignature(data, signature, publicKey) {
        try {
            // 重建PEM格式的公钥
            const pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;

            // 创建验证器 (使用PSS填充)
            const verify = crypto.createVerify('RSA-SHA256');
            verify.update(data, 'utf8');
            verify.end();

            // 验证签名
            return verify.verify(
                pemKey,
                signature,
                'base64',
                {
                    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
                    saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
                }
            );
        } catch (error) {
            console.error('Signature verification failed:', error);
            return false;
        }
    }
}

module.exports = SmsSendService;